﻿#include "stdafx.h"
#include "UBox.h"
#include "Decode.h"
#include "Resource.h"
#include <time.h>


UBox::UBox()
{
	mReceiveFuncQuit = false;
	mReceiveFuncHandle = 0;
}

void UBox::heartbeat()
{
	Decode::Packet p;
	Decode::makeHeartbeat(p, mBoxId);
	int ret = mySend(mSock, (char *)&p[0], p.size(), 0);
}

void UBox::onReceive(const unsigned char * buf, size_t count)
{
	mCurrentFrame.mData.clear();
	for (size_t i = 0; i < count; ++i)
	{
		unsigned char ch = buf[i];
		mCurrentFrame.mData.push_back(ch);
	}

	wstring s1, str;
	mCurrentFrame.mTickCount = GetTickCount();
	mFrameBuffer.push_back(mCurrentFrame);
	hex2wstring(s1, mCurrentFrame.mData, 1);
	s1 = L"接收字节：" + s1;
	showInf(s1.c_str());
}

//数据接收计时器
void UBox::onTimer()
{
	vector<unsigned char> buf;
	takeReceiveBuffer(buf);
	if (buf.empty())
		return;

	onReceive(&buf[0], buf.size());

	mFrameBuffer.clear();
}

void UBox::takeReceiveBuffer(vector<unsigned char> & buf)
{
	OM_LOCK_USERNAMED_AUTO_MUTEX(mReceiveMutex);
	buf.insert(buf.end(), mReceiveBuffer.begin(), mReceiveBuffer.end());
	mReceiveBuffer.clear();
}

//p.push_back(0xFA);
//p.push_back(0xFA);
//p.push_back(getPacketSeq()); //包序列
//p.push_back(0x00); //功能ID
//for (int i = 0; i < 6; i++) {
//	p.push_back(mBoxId[i]);
//}
//p.push_back(0x00);
//p.push_back(0x1A);
//p.push_back(0xFB);
//Decode::makeUploadGpsInfo(p, mMcuId, mImei, mVin, mCcid, mImsi, mHardwareVersion, mFirmwareVersion, mVehicleProtocol);

void UBox::SendFarmeInfo(FrameType ft, wstring frame) {
	bool isSim = false, isCarInfo = false, isIncludeTime = true, isIframe = false;
	bool isGps = false;
	wstring str;
	switch (ft)
	{
	case UBox::GpsInfo:
		str = strGpsInfo;
		isGps = true;
		break;
	case UBox::CanStaticData:
		str = strCanStaticData;
		break;
	case UBox::CarFault:
		str = strCarFault;
		break;
	case UBox::VersionInfo:
		isIncludeTime = false;
		str = strVersionInfo;
		break;
	case UBox::TerminalWarning:
		str = strTerminalWarning;
		break;
	case UBox::TerminalHeartbeat:
		isIncludeTime = false;
		str = strTerminalHeartbeat;
		break;
	case UBox::ActionData:
		str = strActionData;
		break;
	case UBox::SimInfo:
		isSim = true;
		isIncludeTime = false;
		str = strSimInfo;
		break;
	case UBox::GpsLbsInfo:
		str = strGpsLbsInfo;
		break;
	case UBox::LbsInfo:
		str = strLbsInfo;
		break;
	case UBox::CarInfo:
		isIncludeTime = false;
		isCarInfo = true;
		str = strCarInfo;
		break;
	case UBox::HurryDecelerate:
		str = strHurryDecelerate;
		break;
	case UBox::HurryAcceleration:
		str = strHurryAcceleration;
		break;
	case UBox::HurrySwerves:
		str = strHurrySwerves;
		break;
	case UBox::OverSpeed:
		str = strOverSpeed;
		break;
	case UBox::HurryBrakes:
		str = strHurryBrakes;
		break;
	case UBox::Log:
		str = strLog;
		break;
	case UBox::AlarmEvent:
		str = strAlarmEvent;
		break;
	case UBox::ExtendEvent:
		str = strExtendEvent;
		break;
	case UBox::BigGpsInfo:
		isIncludeTime = false;
		str = strBigGpsInfo;
		break;
	case UBox::BigCanStaticData:
		isIncludeTime = false;
		str = strBigCanStaticData;
		break;
	case UBox::HurryDecelerateScene:
		str = strHurryDecelerateScene;
		break;
	case UBox::HurryAccelerationScene:
		str = strHurryAccelerationScene;
		break;
	case UBox::HurrySwervesScene:
		str = strHurrySwervesScene;
		break;
	case UBox::ImpactEventScene:
		str = strImpactEventScene;
		break;
	case UBox::HurryBrakesEventScene:
		str = strHurryBrakesEventScene;
		break;
	case UBox::HurryDecelerateScene2:
		str = strHurryDecelerateScene2;
		break;
	case UBox::HurryAccelerationScene2:
		str = strHurryAccelerationScene2;
		break;
	case UBox::HurrySwervesScene2:
		str = strHurrySwervesScene2;
		break;
	case UBox::ImpactEventScene2:
		str = strImpactEventScene2;
		break;
	case UBox::HurryBrakesEventScene2:
		str = strHurryBrakesEventScene2;
		break;
	case UBox::XingChengStart:
		str = strXingChengStart;
		isGps = true;
		break;
	case UBox::XingChengEnd:
		str = strXingChengEnd;
		isGps = true;
		break;
	case UBox::FrameInfo:
		isIframe = true;
		str = frame;
		break;
	default:
		break;
	}
	Trim(str);
	if (str.size() < 1) {
		MessageBox(AfxGetMainWnd()->m_hWnd, _T("不允许发送空数据！"), _T("提示"), MB_OK | MB_ICONWARNING);
		return;
	}

	time_t tt = time(NULL);//返回时间戳
	tm* t = localtime(&tt);

	Decode::Packet p;
	vector<wstring> v;
	split(v, str, L" ");
	int k = 0, n = 0, m = 0, m2 = 0;
	for (int i = 0, j = 0; i < v.size(); i++) {
		string st;
		wstring2string(st, v[i]);
		if (!isIframe) {
			if (i > 3 && i < 10) //修改为配置的boxId
			{
				st.clear();
				st.push_back(mBoxId[j]);
				st.push_back(mBoxId[j + 1]);
				j += 2;
			}
		}
		int b = (int)strtol(&st[0], nullptr, 16);
		//获取当前时间
		if (isIncludeTime && !isIframe&&i >= 12 && i <= 17) {
			switch (i)
			{
			case 12:
				b = t->tm_hour;
				break;
			case 13:
				b = t->tm_min;
				break;
			case 14:
				b = t->tm_sec;
				break;
			case 15:
				b = t->tm_year - 100;
				break;
			case 16:
				b = t->tm_mon + 1;
				break;
			case 17:
				b = t->tm_mday;
				break;
			default:
				break;
			}
		}
		//经纬度上传值变化
		if (isGps && !isIframe) {
			if (i == 20 && curLocationX < 254) {
				b = curLocationX += 2;
				curLocationX = b;
			}
			if (i == 24 && curLocationY < 254) {
				b = curLocationY += 2;
				curLocationY = b;
			}
		}

		if (isSim && !isIframe) { //如果是SIM卡信息
			if (i >= 12 && i <= 26) //修改为配置的IMSI 
			{
				b = mImsi[k];
				k++;
			}
			if (i >= 27 && i <= 46) //修改为配置的ICCID
			{
				b = mIccid[n];
				n++;
			}
			if (i >= 47 && i <= 66) //修改为配置的SIM Number
			{
				b = mSimNumber[m];
				m++;
			}
		}
		if (isCarInfo && !isIframe) { //车辆信息修改为配置的VIN号
			if (i >= 18 && i <= 34) {
				b = mVin[m2];
				m2++;
			}
		}
		p.push_back(b);
	}
	if (p.size() > 3 && p[0] == 250 && p[1] == 250 && p[p.size() - 1] == 251) {
		Decode::checkBit(&p); //重新计算校验位
	}
	int ret = mySend(mSock, (char *)&p[0], p.size(), 0);

}
//去空格
void UBox::Trim(wstring &s)
{
	if (!s.empty())
	{
		s.erase(0, s.find_first_not_of(' '));
		s.erase(s.find_last_not_of(' ') + 1);
	}
}
void UBox::disconnect()
{
	mReceiveFuncQuit = true;
	WaitForSingleObject(mReceiveFuncHandle, 2500);
}
void UBox::CloseSocket() {
	closesocket(mSock);
	mReceiveFuncQuit = true;
	WaitForSingleObject(mReceiveFuncHandle, 2500);
}
unsigned int UBox::receiveFunc(void * para)
{
	UBox & thisObj = *((UBox*)para);
	while (!thisObj.mReceiveFuncQuit)
	{
		char buf[1024];
		int received = recv(thisObj.mSock, buf, sizeof(buf), 0);
		if (received > 0)
		{
			OM_LOCK_USERNAMED_AUTO_MUTEX(thisObj.mReceiveMutex);
			thisObj.mReceiveBuffer.insert(thisObj.mReceiveBuffer.end(), buf, buf + received);
		}
	}
	_endthreadex(0);
	return 0;
}